// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.ui.metadata;

import java.util.List;

import org.dengues.commons.IDenguesSharedImage;
import org.dengues.commons.ui.swt.ThreeCompositesSashForm;
import org.dengues.commons.utils.ImageUtil;
import org.dengues.core.metadata.MetadataHelper;
import org.dengues.core.metadata.MetadataTable;
import org.dengues.model.database.DBColumn;
import org.dengues.model.database.DBTable;
import org.dengues.ui.i18n.Messages;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * @since 2007-9-14 上午12:52:01
 */
public class CustomizeMetadataDialog extends Dialog {

    private boolean canModifyName = false;

    public static String TITLE = Messages.getString("CustomizeMetadataDialog.cus"); //$NON-NLS-1$

    public static Point SIZE = new Point(700, 400);

    private MetadataTableViewer outputViewer;

    private MetadataTable outputMetadataTable;

    private boolean isReadOnly;

    private MetadataTable inputMetadataTable;

    /**
     * Qiang.Zhang.Adolf@gmail.com MetadataDialog constructor comment.
     * 
     * @param parentShell
     * @param table
     */
    public CustomizeMetadataDialog(Shell parentShell, DBTable table) {
        this(parentShell, MetadataHelper.convertMetadataTable(table));
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com MetadataDialog constructor comment.
     * 
     * @param parentShell
     * @param table
     */
    public CustomizeMetadataDialog(Shell parentShell, MetadataTable metadataTable) {
        super(parentShell);
        setShellStyle(SWT.RESIZE | SWT.APPLICATION_MODAL | SWT.MAX | SWT.MIN | SWT.DIALOG_TRIM);
        this.outputMetadataTable = metadataTable.clone();
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com MetadataDialog constructor comment.
     * 
     * @param parentShell
     * @param table
     */
    public CustomizeMetadataDialog(Shell parentShell, MetadataTable metadataTable, boolean isReadOnly) {
        this(parentShell, metadataTable);
        this.isReadOnly = isReadOnly;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com MetadataDialog constructor comment.
     * 
     * @param shell
     * @param inputMetadataTable
     * @param outputMetadata
     * @param readOnly
     */
    public CustomizeMetadataDialog(Shell shell, MetadataTable inputMetadataTable, MetadataTable outputMetadata, boolean readOnly) {
        this(shell, outputMetadata, readOnly);
        this.inputMetadataTable = inputMetadataTable;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
     */
    @Override
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        newShell.setSize(SIZE);
        newShell.setText(TITLE);
        newShell.setLocation(Display.getCurrent().getActiveShell().toDisplay(100, 100));
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
     */
    @Override
    protected Control createDialogArea(Composite parent) {
        Composite container = (Composite) super.createDialogArea(parent);
        if (inputMetadataTable == null) {
            outputViewer = createTable(container, outputMetadataTable, isReadOnly);
            Table table = outputViewer.getTableViewer().getTable();
            table.setEnabled(!isReadOnly);
            for (TableColumn column : table.getColumns()) {
                column.pack();
            }
        } else {
            ThreeCompositesSashForm sashForm = new ThreeCompositesSashForm(container, SWT.NONE);
            final MetadataTableViewer inputViewer = createTable(sashForm.getLeftComposite(), inputMetadataTable, isReadOnly);
            outputViewer = createTable(sashForm.getRightComposite(), outputMetadataTable, isReadOnly);

            Label label1 = new Label(sashForm.getMidComposite(), SWT.NONE);
            GridDataFactory.swtDefaults().hint(42, 17).applyTo(label1);
            Composite buttonComposite = new Composite(sashForm.getMidComposite(), SWT.BORDER);
            GridLayout gridLayout = new GridLayout(1, true);
            buttonComposite.setLayout(gridLayout);
            GridData gridData = new GridData(GridData.FILL_BOTH);
            buttonComposite.setLayoutData(gridData);
            Label label2 = new Label(sashForm.getMidComposite(), SWT.NONE);
            GridDataFactory.swtDefaults().hint(42, 30).applyTo(label2);

            Composite leftBtnComp = new Composite(buttonComposite, SWT.NONE);

            gridLayout = new GridLayout(1, true);
            gridLayout.marginBottom = 0;
            gridLayout.marginHeight = 0;
            gridLayout.marginLeft = 0;
            gridLayout.marginRight = 0;
            gridLayout.marginTop = 0;
            gridLayout.marginWidth = 0;
            leftBtnComp.setLayout(gridLayout);
            gridData = new GridData(GridData.FILL_BOTH);
            gridData.verticalAlignment = GridData.CENTER;
            leftBtnComp.setLayoutData(gridData);

            // Input => Output
            Button copyToOutput = new Button(leftBtnComp, SWT.NONE);
            copyToOutput.setImage(ImageUtil.getImage(IDenguesSharedImage.METADATA_RIGHT));
            GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(copyToOutput);

            copyToOutput.addSelectionListener(new SelectionAdapter() {

                /*
                 * (non-Javadoc)
                 * 
                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    MetadataTable metadataTable2 = inputViewer.getMetadataTable();
                    outputMetadataTable = metadataTable2.clone();
                    inputMetadataTable = metadataTable2.clone();
                    outputViewer.refreshMetadataTable(inputMetadataTable);
                }
            });
            // Output => Input
            Button copyToInput = new Button(leftBtnComp, SWT.NONE);
            copyToInput.setImage(ImageUtil.getImage(IDenguesSharedImage.METADATA_LEFT));
            GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(copyToOutput);
            copyToInput.addSelectionListener(new SelectionAdapter() {

                /*
                 * (non-Javadoc)
                 * 
                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    MetadataTable metadataTable2 = outputViewer.getMetadataTable();
                    outputMetadataTable = metadataTable2.clone();
                    inputMetadataTable = metadataTable2.clone();
                    inputViewer.refreshMetadataTable(outputMetadataTable);
                }
            });
            sashForm.setGridDatas();
        }
        return container;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "createTable".
     * 
     * @param container
     * @param isReadOnly2
     * @param metadataTable2
     */
    private MetadataTableViewer createTable(Composite container, MetadataTable metadataTable2, boolean isReadOnly2) {
        MetadataTableViewer viewer2 = new MetadataTableViewer(container, metadataTable2, isReadOnly2);
        viewer2.setCanModifyName(isCanModifyName());
        viewer2.initTableInput();
        return viewer2;
    }

    private List<DBColumn> dbColumns;

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.Dialog#okPressed()
     */
    @Override
    protected void okPressed() {
        dbColumns = MetadataHelper.convertDBTable(outputViewer.getMetadataTable());
        super.okPressed();
    }

    /**
     * Getter for dbColumns.
     * 
     * @return the dbColumns
     */
    public List<DBColumn> getDbColumns() {
        return this.dbColumns;
    }

    /**
     * Getter for metadataTable.
     * 
     * @return the metadataTable
     */
    public MetadataTable getOutputMetadataTable() {
        if (outputMetadataTable != null) {
            return this.outputMetadataTable.clone();
        }
        return null;
    }

    /**
     * Getter for canModifyName.
     * 
     * @return the canModifyName
     */
    public boolean isCanModifyName() {
        return this.canModifyName;
    }

    /**
     * Sets the canModifyName.
     * 
     * @param canModifyName the canModifyName to set
     */
    public void setCanModifyName(boolean canModifyName) {
        this.canModifyName = canModifyName;
    }

    /**
     * Getter for inputMetadataTable.
     * 
     * @return the inputMetadataTable
     */
    public MetadataTable getInputMetadataTable() {
        if (inputMetadataTable != null) {
            return this.inputMetadataTable.clone();
        }
        return null;
    }
}
